'use strict'

let {paramcheck} = require('titbit-toolkit')

/**
 * 设定body参数检测规则，以下代码中中间件配置会启用此规则。
 */
 let pck = new paramcheck({
  key: 'body',
  data: {
    username: {
      must: true,
    },
    passwd: {
      must: true
    }
  }
})

class admin {

  constructor () {
    //param默认就是/:id，若要改变路由，则可以设置此属性，比如设置为/:name
    //this.param = '/:id'
  }

  //默认传递app.service
  async init(serv) {
    //初始化时使用this.admin指向app.service.admin
    //在请求函数里就不必使用c.service.admin获取模型实例
    //目的就是少写代码，减少对象属性引用的层级
    this.admin = serv.admin
  }

  /**
   * 获取资源具体内容
   * @param {context} c
   * @returns 
   */
  async get (c) {
    let adm = await this.admin.where('id', c.param.id).get([
                                'id', 'username', 'role', 'level'
                              ])

    if (!adm) return c.status(404).send('没有此用户')

    return c.send(adm)
  }

  /**
   * 创建资源
   * @param {context} c
   * @returns 
   */
  async post (c) {
    try {
      //可以使用this.admin替换c.service.admin
      let r = await c.service.admin.create(c.body)
      c.send(r)
    } catch (err) {
      return c.status(400).send(err.message)
    }
  }

  /**
   * 更新资源
   * @param {context} c
   * @returns 
   */
  async put (c) {
    let data = {}
    let kcount = 0

    for (let k in c.body) {
      switch (k) {
        case 'forbid':
        case 'username':
        case 'passwd':
        case 'email':
          data[k] = c.body
          kcount += 1
          break
      }
    }

    if (kcount === 0) {
      return c.status(400).send('数据提交有误')
    }

    let count = 0
    if (c.body.passwd) {
      count = await this.admin.updatePasswd(c.param.id, data)
    } else {
      count = await this.admin.where('id', c.param.id).update(data)
    }

    c.send({data: count})
  }

  /**
   * 获取列表
   * @param {context} c
   * @returns 
   */
  async list (c) {
    let alist = await this.admin.order('username', 'asc')
                          .order('create_time', 'desc')
                          .select(['id', 'username', 'role', 'level', 'create_time'])

    c.send(alist)
  }

  /**
   * 删除资源
   * @param {context} c
   * @returns 
   */
  async delete (c) {
    let adm = await this.admin.where('id', c.param.id).get()
    
    if (!adm) return c.status(403).send('无法删除不存在的用户。')

    adm = await this.admin.where('id', c.param.id)
                    .where('role != ?', ['super'])
                    .returning(['id', 'username'])
                    .delete()
    c.send(adm)
  }

  __mid () {
    return [
      {
        //针对post函数启用参数检测，如果没有提交username和passwd会自动返回400错误。
        middleware: pck,
        path: [ 'post' ]
      },

      {
        //权限检测，只有super级别的用户可以更新其他人的密码和用户名，admin级别的用户只能更新自己的密码和用户名。
        middleware: async (c, next) => {
          if (c.method === 'POST') {
            if (c.box.user.level !== c.service.admin.roleLevel.super) {
              return c.status(403).send('非super用户，不能创建管理员')
            }
            return await next()
          }

          if (c.param.id === 'self') {
            c.param.id = c.box.user.id
          }

          if (c.method === 'DELETE' && c.box.user.id === c.param.id) {
            return c.status(403).send('用户不能删除自己')
          }
          
          if (c.box.user.id !== c.param.id) {
            if (c.box.user.level !== c.service.admin.roleLevel.super) {
              return c.status(403).send('没有权限执行此操作')
            }
          }

          await next()
        },

        path: [ 'post', 'put', 'delete' ]
      }
    ]
  }
  
}

module.exports = admin
